package org.lixf.io.zip;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtility {
    private static ZipEntry getZipEntry(Path root, Path current) {
        String zipEntryName = root.relativize(current).toString();
        if (Files.isDirectory(current)) {
            // 应该写"/"
            zipEntryName = zipEntryName + "/";
        }
        return new ZipEntry(zipEntryName);
    }

    public static void compress(String sourcePath, String targetPath) throws IOException {
        long start = System.currentTimeMillis();
        final Path rootPath = Paths.get(sourcePath);
        try (ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(targetPath)))) {
            Files.walkFileTree(Paths.get(sourcePath), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    if (dir.compareTo(rootPath) == 0) {
                        return FileVisitResult.CONTINUE;
                    }
                    zip.putNextEntry(getZipEntry(rootPath, dir));
                    zip.closeEntry();
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    zip.putNextEntry(getZipEntry(rootPath, file));
                    Files.copy(file, zip);
                    zip.closeEntry();
                    return FileVisitResult.CONTINUE;
                }
            });
        }
    }

    public static void main(String[] args) throws IOException {
        long startTime = System.currentTimeMillis();
        ZipUtility.compress("C:\\Users\\lixf\\Desktop\\a", "C:\\Users\\lixf\\Desktop\\test.zip");
        System.out.println(System.currentTimeMillis() - startTime);
    }
}